const express = require('express');
const { InputSecurity } = require('../security');
const { DataConsistency, TransactionManager, ExceptionHandler } = require('../consistency');
const { PerformanceMonitor } = require('../performance');
const Article = require('../models/Article');
const dataSyncService = require('./data-sync');

class ArticlesService {
    constructor() {
        this.app = express();
        this.port = process.env.ARTICLES_SERVICE_PORT || 3002;
        this.dataConsistency = new DataConsistency();
        this.transactionManager = new TransactionManager();
        this.exceptionHandler = new ExceptionHandler();
        this.performanceMonitor = new PerformanceMonitor();
        
        this.categories = [
            'technology', 'travel', 'lifestyle', 'business', 'education',
            'health', 'finance', 'entertainment', 'sports', 'science',
            'art', 'music', 'food', 'fashion', 'automotive',
            'real_estate', 'career', 'parenting', 'relationships', 'self_improvement'
        ];
        
        this.setupMiddleware();
        this.setupRoutes();
        this.setupSearchIndex();
        this.initializeDataConsistency();
    }

    setupMiddleware() {
        this.app.use(express.json({ limit: '10mb' }));
        this.app.use(express.urlencoded({ extended: true }));
        
        // 性能监控
        this.app.use((req, res, next) => {
            const startTime = Date.now();
            res.on('finish', () => {
                const responseTime = Date.now() - startTime;
                this.performanceMonitor.recordRequest(req.path, req.method, responseTime, res.statusCode);
            });
            next();
        });
    }

    setupRoutes() {
        // 创建文章
        this.app.post('/articles', async (req, res) => {
            try {
                const { title, category, theme, keywords, content, status = 'draft', authorId } = req.body;
                
                // 输入验证
                if (!title || !content || !authorId) {
                    return res.status(400).json({ 
                        success: false, 
                        message: '标题、内容和作者ID为必填项' 
                    });
                }
                
                // XSS防护和HTML清理
                const sanitizedTitle = InputSecurity.preventXSS(title);
                const sanitizedContent = InputSecurity.sanitizeHtml(content);
                
                // 创建文章
                const article = await Article.create({
                    title: sanitizedTitle,
                    category,
                    theme,
                    keywords,
                    content: sanitizedContent,
                    status,
                    authorId: parseInt(authorId)
                });
                
                // 数据同步
                await dataSyncService.queueSyncTask('create', 'article', article.id, null, article);
                
                res.status(201).json({
                    success: true,
                    message: '文章创建成功',
                    data: article
                });
            } catch (error) {
                this.exceptionHandler.handleError(res, error, '创建文章失败');
            }
        });
        
        // 获取文章列表
        this.app.get('/articles', async (req, res) => {
            try {
                const page = parseInt(req.query.page) || 1;
                const limit = parseInt(req.query.limit) || 10;
                const status = req.query.status;
                const category = req.query.category;
                const authorId = req.query.authorId;
                
                const filters = {};
                if (status) filters.status = status;
                if (category) filters.category = category;
                if (authorId) filters.authorId = parseInt(authorId);
                
                const result = await Article.findAll(page, limit, filters);
                
                res.json({
                    success: true,
                    data: {
                        articles: result.articles,
                        pagination: {
                            page: result.page,
                            limit: result.limit,
                            total: result.total,
                            totalPages: result.totalPages
                        }
                    }
                });
            } catch (error) {
                this.exceptionHandler.handleError(res, error, '获取文章列表失败');
            }
        });
        
        // 获取单篇文章
        this.app.get('/articles/:id', async (req, res) => {
            try {
                const articleId = parseInt(req.params.id);
                const article = await Article.findById(articleId);
                
                if (!article) {
                    return res.status(404).json({ 
                        success: false, 
                        message: '文章不存在' 
                    });
                }
                
                res.json({
                    success: true,
                    data: article
                });
            } catch (error) {
                this.exceptionHandler.handleError(res, error, '获取文章失败');
            }
        });
        
        // 更新文章
        this.app.put('/articles/:id', async (req, res) => {
            try {
                const articleId = parseInt(req.params.id);
                const article = await Article.findById(articleId);
                
                if (!article) {
                    return res.status(404).json({ 
                        success: false, 
                        message: '文章不存在' 
                    });
                }
                
                const oldData = {
                    title: article.title,
                    content: article.content,
                    status: article.status
                };
                
                // XSS防护和HTML清理
                if (req.body.title) {
                    req.body.title = InputSecurity.preventXSS(req.body.title);
                }
                if (req.body.content) {
                    req.body.content = InputSecurity.sanitizeHtml(req.body.content);
                }
                
                // 更新文章
                const updatedArticle = await article.update(req.body);
                
                // 数据同步
                await dataSyncService.queueSyncTask('update', 'article', article.id, oldData, updatedArticle);
                
                res.json({
                    success: true,
                    message: '文章更新成功',
                    data: updatedArticle
                });
            } catch (error) {
                this.exceptionHandler.handleError(res, error, '更新文章失败');
            }
        });
        
        // 删除文章
        this.app.delete('/articles/:id', async (req, res) => {
            try {
                const articleId = parseInt(req.params.id);
                const article = await Article.findById(articleId);
                
                if (!article) {
                    return res.status(404).json({ 
                        success: false, 
                        message: '文章不存在' 
                    });
                }
                
                const oldData = {
                    title: article.title,
                    content: article.content,
                    status: article.status
                };
                
                // 删除文章
                await article.delete();
                
                // 数据同步
                await dataSyncService.queueSyncTask('delete', 'article', article.id, oldData, null);
                
                res.json({
                    success: true,
                    message: '文章删除成功'
                });
            } catch (error) {
                this.exceptionHandler.handleError(res, error, '删除文章失败');
            }
        });
        
        // 搜索文章
        this.app.get('/articles/search', async (req, res) => {
            try {
                const query = req.query.q;
                const page = parseInt(req.query.page) || 1;
                const limit = parseInt(req.query.limit) || 10;
                
                if (!query) {
                    return res.status(400).json({ 
                        success: false, 
                        message: '搜索关键词不能为空' 
                    });
                }
                
                // 使用PostgreSQL全文搜索
                const client = await require('../config/database').postgresPool.connect();
                
                try {
                    const offset = (page - 1) * limit;
                    
                    const searchQuery = `
                        SELECT a.*, 
                               ts_rank(
                                   to_tsvector('english', COALESCE(a.title, '') || ' ' || COALESCE(a.content, '')),
                                   plainto_tsquery('english', $1)
                               ) as rank
                        FROM articles a
                        WHERE a.status = 'published'
                        AND to_tsvector('english', COALESCE(a.title, '') || ' ' || COALESCE(a.content, '')) 
                            @@ plainto_tsquery('english', $1)
                        ORDER BY rank DESC
                        LIMIT $2 OFFSET $3
                    `;
                    
                    const countQuery = `
                        SELECT COUNT(*) 
                        FROM articles a
                        WHERE a.status = 'published'
                        AND to_tsvector('english', COALESCE(a.title, '') || ' ' || COALESCE(a.content, '')) 
                            @@ plainto_tsquery('english', $1)
                    `;
                    
                    const [articlesResult, countResult] = await Promise.all([
                        client.query(searchQuery, [query, limit, offset]),
                        client.query(countQuery, [query])
                    ]);
                    
                    const articles = articlesResult.rows.map(row => new Article(row));
                    const total = parseInt(countResult.rows[0].count);
                    
                    res.json({
                        success: true,
                        data: {
                            articles,
                            pagination: {
                                page,
                                limit,
                                total,
                                totalPages: Math.ceil(total / limit)
                            }
                        }
                    });
                } finally {
                    client.release();
                }
            } catch (error) {
                this.exceptionHandler.handleError(res, error, '搜索文章失败');
            }
        });
        
        // 获取文章分类
        this.app.get('/articles/categories', (req, res) => {
            res.json({
                success: true,
                data: this.categories
            });
        });
        
        // 健康检查
        this.app.get('/health', (req, res) => {
            res.json({
                success: true,
                message: '文章服务运行正常',
                timestamp: new Date().toISOString()
            });
        });
        // 健康检查
        this.app.get('/health', (req, res) => {
            res.json({
                service: 'articles-service',
                status: 'healthy',
                articleCount: this.articles.length,
                timestamp: Date.now()
            });
        });

        // 文章列表
        this.app.get('/api/articles', this.getArticles.bind(this));
        
        // 获取单个文章
        this.app.get('/api/articles/:id', this.getArticle.bind(this));
        
        // 创建文章
        this.app.post('/api/articles', this.createArticle.bind(this));
        
        // 更新文章
        this.app.put('/api/articles/:id', this.updateArticle.bind(this));
        
        // 删除文章
        this.app.delete('/api/articles/:id', this.deleteArticle.bind(this));
        
        // 文章搜索
        this.app.get('/api/articles/search', this.searchArticles.bind(this));
        
        // 分类管理
        this.app.get('/api/categories', this.getCategories.bind(this));
        
        // 文章统计
        this.app.get('/api/articles/stats', this.getArticleStats.bind(this));
        
        // 批量操作
        this.app.post('/api/articles/batch', this.batchOperations.bind(this));
    }

    // 初始化数据一致性
    initializeDataConsistency() {
        this.articles.forEach(article => {
            article.checksum = this.dataConsistency.generateChecksum(article);
            this.dataConsistency.registerChecksum(`article_${article.id}`, article);
        });
    }

    // 设置搜索索引
    setupSearchIndex() {
        this.searchIndex = new Map();
        
        // 构建初始索引
        this.articles.forEach(article => {
            this.indexArticle(article);
        });
    }

    // 索引文章
    indexArticle(article) {
        const words = [
            ...article.title.toLowerCase().split(/\s+/),
            ...article.keywords.toLowerCase().split(/\s*,\s*/),
            ...article.theme.toLowerCase().split(/\s+/)
        ];
        
        words.forEach(word => {
            if (!this.searchIndex.has(word)) {
                this.searchIndex.set(word, new Set());
            }
            this.searchIndex.get(word).add(article.id);
        });
    }

    // 获取文章列表
    getArticles(req, res) {
        try {
            const { 
                status, 
                category, 
                authorId, 
                page = 1, 
                limit = 10,
                sortBy = 'createdAt',
                sortOrder = 'desc'
            } = req.query;
            
            let filteredArticles = [...this.articles];
            
            // 过滤逻辑
            if (status) {
                filteredArticles = filteredArticles.filter(article => article.status === status);
            }
            
            if (category) {
                filteredArticles = filteredArticles.filter(article => article.category === category);
            }
            
            if (authorId) {
                filteredArticles = filteredArticles.filter(article => article.authorId === parseInt(authorId));
            }
            
            // 排序
            filteredArticles.sort((a, b) => {
                let aValue = a[sortBy];
                let bValue = b[sortBy];
                
                if (sortBy === 'createdAt' || sortBy === 'updatedAt') {
                    aValue = new Date(aValue).getTime();
                    bValue = new Date(bValue).getTime();
                }
                
                return sortOrder === 'desc' ? bValue - aValue : aValue - bValue;
            });
            
            // 分页
            const pageNum = parseInt(page);
            const limitNum = parseInt(limit);
            const startIndex = (pageNum - 1) * limitNum;
            const endIndex = startIndex + limitNum;
            const paginatedArticles = filteredArticles.slice(startIndex, endIndex);
            
            res.json({
                success: true,
                data: paginatedArticles,
                pagination: {
                    page: pageNum,
                    limit: limitNum,
                    total: filteredArticles.length,
                    totalPages: Math.ceil(filteredArticles.length / limitNum)
                },
                filters: {
                    status,
                    category,
                    authorId,
                    sortBy,
                    sortOrder
                }
            });
            
        } catch (error) {
            this.exceptionHandler.logException(error, { endpoint: '/api/articles' });
            res.status(500).json({
                success: false,
                message: '获取文章列表失败'
            });
        }
    }

    // 获取单个文章
    getArticle(req, res) {
        try {
            const articleId = parseInt(req.params.id);
            const article = this.articles.find(a => a.id === articleId);
            
            if (!article) {
                return res.status(404).json({
                    success: false,
                    message: '文章不存在'
                });
            }
            
            // 数据一致性检查
            const consistency = this.dataConsistency.verifyConsistency(`article_${articleId}`, article);
            
            res.json({
                success: true,
                data: article,
                consistency
            });
            
        } catch (error) {
            this.exceptionHandler.logException(error, { endpoint: '/api/articles/:id' });
            res.status(500).json({
                success: false,
                message: '获取文章失败'
            });
        }
    }

    // 创建文章
    async createArticle(req, res) {
        const transactionId = this.transactionManager.beginTransaction('create_article', this.articles);
        
        try {
            const { title, category, theme, keywords, content, status = 'draft' } = req.body;
            
            // 输入验证
            if (!title || !content) {
                return res.status(400).json({
                    success: false,
                    message: '标题和内容不能为空'
                });
            }
            
            if (title.length > 200) {
                return res.status(400).json({
                    success: false,
                    message: '标题长度不能超过200个字符'
                });
            }
            
            if (content.length > 100000) {
                return res.status(400).json({
                    success: false,
                    message: '内容长度不能超过100000个字符'
                });
            }
            
            // XSS防护和HTML清理
            const sanitizedTitle = InputSecurity.preventXSS(title);
            const sanitizedContent = InputSecurity.sanitizeHtml(content);
            
            // 生成文章ID
            const newArticleId = ++this.lastArticleId;
            
            // 创建新文章
            const newArticle = {
                id: newArticleId,
                title: sanitizedTitle,
                category: category || 'general',
                theme: theme || '',
                keywords: keywords || '',
                content: sanitizedContent,
                status: status,
                authorId: 1, // 从认证服务获取实际用户ID
                createdAt: new Date().toISOString(),
                updatedAt: new Date().toISOString(),
                checksum: ''
            };
            
            // 生成校验和
            newArticle.checksum = this.dataConsistency.generateChecksum(newArticle);
            
            // 记录操作
            this.transactionManager.recordOperation(transactionId, {
                type: 'CREATE_ARTICLE',
                articleId: newArticleId,
                data: newArticle
            });
            
            // 添加到文章列表
            this.articles.push(newArticle);
            
            // 更新搜索索引
            this.indexArticle(newArticle);
            
            // 注册数据校验
            this.dataConsistency.registerChecksum(`article_${newArticleId}`, newArticle);
            
            // 提交事务
            this.transactionManager.commitTransaction(transactionId);
            
            res.status(201).json({
                success: true,
                message: '文章创建成功',
                data: newArticle
            });
            
        } catch (error) {
            // 回滚事务
            const snapshot = this.transactionManager.rollbackTransaction(transactionId);
            if (snapshot) {
                this.articles = snapshot;
            }
            
            this.exceptionHandler.logException(error, { 
                endpoint: '/api/articles', 
                transactionId,
                operation: 'CREATE_ARTICLE'
            });
            
            res.status(500).json({
                success: false,
                message: '创建文章失败'
            });
        }
    }

    // 更新文章
    async updateArticle(req, res) {
        const transactionId = this.transactionManager.beginTransaction('update_article', this.articles);
        
        try {
            const articleId = parseInt(req.params.id);
            const articleIndex = this.articles.findIndex(a => a.id === articleId);
            
            if (articleIndex === -1) {
                return res.status(404).json({
                    success: false,
                    message: '文章不存在'
                });
            }
            
            const { title, category, theme, keywords, content, status } = req.body;
            const originalArticle = { ...this.articles[articleIndex] };
            
            // 更新字段
            if (title !== undefined) {
                if (title.length > 200) {
                    return res.status(400).json({
                        success: false,
                        message: '标题长度不能超过200个字符'
                    });
                }
                this.articles[articleIndex].title = InputSecurity.preventXSS(title);
            }
            
            if (content !== undefined) {
                if (content.length > 100000) {
                    return res.status(400).json({
                        success: false,
                        message: '内容长度不能超过100000个字符'
                    });
                }
                this.articles[articleIndex].content = InputSecurity.sanitizeHtml(content);
            }
            
            if (category !== undefined) this.articles[articleIndex].category = category;
            if (theme !== undefined) this.articles[articleIndex].theme = theme;
            if (keywords !== undefined) this.articles[articleIndex].keywords = keywords;
            if (status !== undefined) this.articles[articleIndex].status = status;
            
            this.articles[articleIndex].updatedAt = new Date().toISOString();
            this.articles[articleIndex].checksum = this.dataConsistency.generateChecksum(this.articles[articleIndex]);
            
            // 记录操作
            this.transactionManager.recordOperation(transactionId, {
                type: 'UPDATE_ARTICLE',
                articleId: articleId,
                originalData: originalArticle,
                newData: this.articles[articleIndex]
            });
            
            // 更新搜索索引
            this.indexArticle(this.articles[articleIndex]);
            
            // 更新数据校验
            this.dataConsistency.registerChecksum(`article_${articleId}`, this.articles[articleIndex]);
            
            // 提交事务
            this.transactionManager.commitTransaction(transactionId);
            
            res.json({
                success: true,
                message: '文章更新成功',
                data: this.articles[articleIndex]
            });
            
        } catch (error) {
            // 回滚事务
            const snapshot = this.transactionManager.rollbackTransaction(transactionId);
            if (snapshot) {
                this.articles = snapshot;
            }
            
            this.exceptionHandler.logException(error, { 
                endpoint: '/api/articles/:id', 
                transactionId,
                operation: 'UPDATE_ARTICLE'
            });
            
            res.status(500).json({
                success: false,
                message: '更新文章失败'
            });
        }
    }

    // 删除文章
    async deleteArticle(req, res) {
        const transactionId = this.transactionManager.beginTransaction('delete_article', this.articles);
        
        try {
            const articleId = parseInt(req.params.id);
            const articleIndex = this.articles.findIndex(a => a.id === articleId);
            
            if (articleIndex === -1) {
                return res.status(404).json({
                    success: false,
                    message: '文章不存在'
                });
            }
            
            const deletedArticle = this.articles[articleIndex];
            
            // 记录操作
            this.transactionManager.recordOperation(transactionId, {
                type: 'DELETE_ARTICLE',
                articleId: articleId,
                data: deletedArticle
            });
            
            // 删除文章
            this.articles.splice(articleIndex, 1);
            
            // 从搜索索引中移除
            this.removeArticleFromIndex(articleId);
            
            // 提交事务
            this.transactionManager.commitTransaction(transactionId);
            
            res.json({
                success: true,
                message: '文章删除成功',
                data: { id: articleId }
            });
            
        } catch (error) {
            // 回滚事务
            const snapshot = this.transactionManager.rollbackTransaction(transactionId);
            if (snapshot) {
                this.articles = snapshot;
            }
            
            this.exceptionHandler.logException(error, { 
                endpoint: '/api/articles/:id', 
                transactionId,
                operation: 'DELETE_ARTICLE'
            });
            
            res.status(500).json({
                success: false,
                message: '删除文章失败'
            });
        }
    }

    // 从搜索索引中移除文章
    removeArticleFromIndex(articleId) {
        for (const [word, articleIds] of this.searchIndex.entries()) {
            articleIds.delete(articleId);
            if (articleIds.size === 0) {
                this.searchIndex.delete(word);
            }
        }
    }

    // 搜索文章
    searchArticles(req, res) {
        try {
            const { q, category, page = 1, limit = 10 } = req.query;
            
            if (!q) {
                return res.status(400).json({
                    success: false,
                    message: '搜索关键词不能为空'
                });
            }
            
            const searchTerms = q.toLowerCase().split(/\s+/);
            let matchedArticleIds = new Set();
            
            // 简单搜索算法
            searchTerms.forEach(term => {
                if (this.searchIndex.has(term)) {
                    const articleIds = this.searchIndex.get(term);
                    articleIds.forEach(id => matchedArticleIds.add(id));
                }
            });
            
            let results = Array.from(matchedArticleIds)
                .map(id => this.articles.find(a => a.id === id))
                .filter(article => article && article.status === 'published');
            
            // 分类过滤
            if (category) {
                results = results.filter(article => article.category === category);
            }
            
            // 分页
            const pageNum = parseInt(page);
            const limitNum = parseInt(limit);
            const startIndex = (pageNum - 1) * limitNum;
            const endIndex = startIndex + limitNum;
            const paginatedResults = results.slice(startIndex, endIndex);
            
            res.json({
                success: true,
                data: paginatedResults,
                searchInfo: {
                    query: q,
                    totalResults: results.length,
                    searchTerms
                },
                pagination: {
                    page: pageNum,
                    limit: limitNum,
                    total: results.length,
                    totalPages: Math.ceil(results.length / limitNum)
                }
            });
            
        } catch (error) {
            this.exceptionHandler.logException(error, { endpoint: '/api/articles/search' });
            res.status(500).json({
                success: false,
                message: '搜索文章失败'
            });
        }
    }

    // 获取分类列表
    getCategories(req, res) {
        try {
            const categoryStats = this.categories.map(category => ({
                name: category,
                count: this.articles.filter(a => a.category === category && a.status === 'published').length
            }));
            
            res.json({
                success: true,
                data: categoryStats
            });
            
        } catch (error) {
            this.exceptionHandler.logException(error, { endpoint: '/api/categories' });
            res.status(500).json({
                success: false,
                message: '获取分类列表失败'
            });
        }
    }

    // 获取文章统计
    getArticleStats(req, res) {
        try {
            const stats = {
                total: this.articles.length,
                published: this.articles.filter(a => a.status === 'published').length,
                draft: this.articles.filter(a => a.status === 'draft').length,
                byCategory: {},
                byMonth: {}
            };
            
            // 分类统计
            this.categories.forEach(category => {
                stats.byCategory[category] = this.articles.filter(a => a.category === category).length;
            });
            
            // 月度统计
            this.articles.forEach(article => {
                const month = new Date(article.createdAt).toISOString().slice(0, 7); // YYYY-MM
                stats.byMonth[month] = (stats.byMonth[month] || 0) + 1;
            });
            
            res.json({
                success: true,
                data: stats
            });
            
        } catch (error) {
            this.exceptionHandler.logException(error, { endpoint: '/api/articles/stats' });
            res.status(500).json({
                success: false,
                message: '获取文章统计失败'
            });
        }
    }

    // 批量操作
    batchOperations(req, res) {
        try {
            const { operations } = req.body;
            
            if (!Array.isArray(operations)) {
                return res.status(400).json({
                    success: false,
                    message: '操作列表格式不正确'
                });
            }
            
            const results = [];
            
            operations.forEach(operation => {
                try {
                    switch (operation.type) {
                        case 'publish':
                            const article = this.articles.find(a => a.id === operation.articleId);
                            if (article) {
                                article.status = 'published';
                                article.updatedAt = new Date().toISOString();
                                results.push({ 
                                    type: 'publish', 
                                    articleId: operation.articleId, 
                                    success: true 
                                });
                            }
                            break;
                        case 'delete':
                            const index = this.articles.findIndex(a => a.id === operation.articleId);
                            if (index !== -1) {
                                this.articles.splice(index, 1);
                                results.push({ 
                                    type: 'delete', 
                                    articleId: operation.articleId, 
                                    success: true 
                                });
                            }
                            break;
                    }
                } catch (error) {
                    results.push({ 
                        type: operation.type, 
                        articleId: operation.articleId, 
                        success: false, 
                        error: error.message 
                    });
                }
            });
            
            res.json({
                success: true,
                data: results
            });
            
        } catch (error) {
            this.exceptionHandler.logException(error, { endpoint: '/api/articles/batch' });
            res.status(500).json({
                success: false,
                message: '批量操作失败'
            });
        }
    }

    // 启动服务
    start() {
        return this.app.listen(this.port, () => {
            console.log(`📝 Articles Service running on port ${this.port}`);
            console.log(`📊 Health check: http://localhost:${this.port}/health`);
            console.log(`🔍 Search index built with ${this.searchIndex.size} terms`);
        });
    }
}

// 如果直接运行此文件，启动服务
if (require.main === module) {
    const articlesService = new ArticlesService();
    articlesService.start();
}

module.exports = ArticlesService;